package client.control;

import base.BaseValue;
import client.UserState;
import client.assets.Icons;
import client.entity.Message;
import client.ui.view.base.FrameBase;
import com.alibaba.fastjson.JSONObject;
import util.CacheUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
  * @Description 聊天控制，socket的封装
  * @author 孔明浩
  * @Date 2020/4/12
  */
public class ChatControl {
    private static int testNum = 0;
    private int num;
    private final static int RETRY_TIME = 5;
    private static int registerCount = 0;
    private static int sendCount = 0;
    private static int receiveCount = 0;
    private int userId;
    private Executor fixedThreadPool = Executors.newFixedThreadPool(6);
    private Socket socket;
    private DataInputStream inputStream;
    private DataOutputStream outputStream;
    private static boolean stop = false;
    private final List<Message> messages = new ArrayList<>();
    private static TrayIcon trayIcon;

    ChatControl(){
        this.num = testNum;
        testNum++;
        reconnect();
        SystemTray tray = SystemTray.getSystemTray();
        trayIcon = new TrayIcon(Icons.shop.getImage(), "闲置物品交易平台");
        //Let the system resize the image if needed
        trayIcon.setImageAutoSize(true);
        //添加托盘图标
        trayIcon.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JFrame f = FrameBase.frameBaseList.get(0);
                f.setVisible(true);
                f.setExtendedState(JFrame.NORMAL);
            }
        });
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
    public void register(int userId){
        System.out.println("register "+num);
        ResponseEntity responseEntity = new ResponseEntity(2, "注册",userId + "");
        String json = responseEntity.toIntJsonString();
        try {
            outputStream.writeUTF(json);
            outputStream.flush();
            String result = inputStream.readUTF();
            JSONObject object = JSONObject.parseObject(result);
            if (object.getInteger("code") == 0){
                System.out.println("注册成功");
                this.userId = userId;
                receive();
            }
        } catch (IOException e){
            e.printStackTrace();

            if (registerCount <= RETRY_TIME){
                System.out.println("register" + registerCount);
                registerCount++;
                register(userId);
            } else {
                System.out.println("尝试注册失败");
                registerCount = 0;
            }
        }
    }

    public void send(Message message) {
        ResponseEntity responseEntity = new ResponseEntity(0, "",
                JSONObject.toJSONStringWithDateFormat(message, "yyyy-MM-dd HH:mm"));
        String json = JSONObject.toJSONString(responseEntity);
        CacheUtil.writeOtherId(userId, message.getReceiver());
        try {
            outputStream.writeUTF(json);
            outputStream.flush();
        } catch (IOException e) {
            if (sendCount == 0){
                e.printStackTrace();
            }
            if (sendCount <= RETRY_TIME){
                System.out.println("sending" + sendCount);
                sendCount++;
                send(message);
            } else {
                System.out.println("尝试发送失败");
                sendCount = 0;
            }
        }
    }

    public void receive() {
        fixedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try{
                        String result = inputStream.readUTF();
                        JSONObject object = JSONObject.parseObject(result);
                        if (object.getInteger("code") == 0){
                            Message message = JSONObject.parseObject(object.getString("data"), Message.class);
                            if (message.getSender() != UserState.getId()){
                                trayIcon.displayMessage("新消息", message.getText(), TrayIcon.MessageType.NONE);
                            }
                            //写入聊天记录到文件
                            CacheUtil.write(userId, message);
                            CacheUtil.writeOtherId(userId, message.getSender());
                            Thread.sleep(200);
                            messages.add(message);
                        }
                    } catch (IOException | InterruptedException e){
                        if (receiveCount == 0){
                            e.printStackTrace();
                        }
                        if (receiveCount <= RETRY_TIME){
                            System.out.println("retry" + receiveCount);
                            receiveCount++;
                            if (receiveCount > RETRY_TIME){
                                System.out.println("socket连接丢失");
                                receiveCount = 0;
                                reconnect();
                                return;
                            }
                            receive();
                        }
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public List<Message> getMessages(){
        if (messages.size() == 0){
            return new ArrayList<>();
        } else {
            List<Message> messageList =  new ArrayList<>(messages);
            messages.clear();
            return messageList;
        }
    }

    public void closeSocket() {
        try {
            socket.close();
            outputStream.close();
            inputStream.close();
        } catch (IOException e){
            e.printStackTrace();
        }

    }

    public void reconnect(){
        try {
            socket = new Socket(BaseValue.host,BaseValue.chatPort);
            inputStream = new DataInputStream(socket.getInputStream());
            outputStream = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("socket启动失败");
        }
    }

}
